// 阿里云分片上传功能封装
// 简单上传文档地址：https://help.aliyun.com/document_detail/383950.html
// 分片上传文档地址：https://help.aliyun.com/document_detail/383952.html
// 文件小于100m的时候，使用简单上传，大于100m再使用分片上传

import { nanoid } from 'nanoid'
import { ossConfig, ossCredentials } from '@/api/oss'
import { getExt } from '@/utils'

const extDict = {
  '.mp3': 'audio',
  '.aac': 'audio',
  '.flac': 'audio',
  '.mp4': 'video',
  '.mov': 'video',
}

let config
export async function getClientConfig() {
  return new Promise((resolve, reject) => {
    Promise.all([ossConfig(), ossCredentials()]).then((result) => {
      resolve({ ...result[0], ...result[1] })
    })
  })
}

export function getDomain() {
  return new Promise(async (resolve, reject) => {
    if (sessionStorage.getItem('oss_domain')) {
      resolve(sessionStorage.getItem('oss_domain'))
      return
    }
    config = await getClientConfig()
    sessionStorage.setItem('oss_domain', config.domain)
    resolve(config.domain)
  })
}

export function getOSSRootDir() {
  return new Promise(async (resolve, reject) => {
    if (sessionStorage.getItem('OSS_ROOT_DIR')) {
      resolve(sessionStorage.getItem('OSS_ROOT_DIR'))
      return
    }
    config = await getClientConfig()
    sessionStorage.setItem('OSS_ROOT_DIR', config.root_dir)
    resolve(config.root_dir)
  })
}


async function initClient() {
  config = await getClientConfig()
  sessionStorage.setItem('oss_domain', config.domain)
  sessionStorage.setItem('OSS_ROOT_DIR', config.root_dir)
  return new OSS({
    // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
    accessKeyId: config.access_key_id,
    accessKeySecret: config.access_key_secret,
    // 从STS服务获取的安全令牌（SecurityToken）。
    stsToken: config.security_token,
    // 填写Bucket名称。
    bucket: config.bucket
  });
}

// 简单上传
async function simplePut (file) {
  const client = await initClient()
  let fileName = nanoid(32)
  const ext = getExt(file)
  return new Promise((resolve, reject) => {
    let bucket = 'image'
    if (extDict[ext]) bucket = extDict[ext]
    client.put(`${config.root_dir}/${bucket}/${fileName}${ext}`, file).then(result => {
      resolve({
        localFileName: file.name,
        webUrl: `${config.domain}/${result.name}`,
        fileName: result.name
      })
    })
  })
}

// 分片上传
async function multiplePut(file, callback) {
  const client = await initClient()
  let fileName = nanoid(32)
  const ext = getExt(file)
  const options = {
    progress: (p, cpt, res) => {
      console.log(p);
      callback && callback(p)
    },
    // 设置并发上传的分片数量。
    parallel: 6,
    // 设置分片大小。默认值为1 MB，最小值为100 KB。
    partSize: 2 * 1024 * 1024,
  }
  return new Promise((resolve, reject) => {
    let bucket = 'image'
    if (extDict[ext]) bucket = extDict[ext]
    client.multipartUpload(`${config.root_dir}/${bucket}/${fileName}${ext}`, file, {
      ...options
    }).then(result => {
      resolve({
        localFileName: file.name,
        webUrl: `${config.domain}/${result.name}`,
        fileName: result.name
      })
    })
  })
}

/*
 file: 要上传的文件
 callback: 如果是分片上传的话，上传进度的回调
 具体使用方法参考：src -> components -> architect -> pitDesign -> video.vue
*/
export async function ossUploadFile(file, callback) {
  file = file.raw
  console.log('view size: ', file.size)
  const fileSize = file.size
  if (fileSize / 1024 / 1024 > 100) {
    console.log('需要使用分片上传')
    return multiplePut(file, callback)
  } else {
    console.log('使用简单上传文件即可')
    return simplePut(file)
  }
}
